#ifndef MEDIABUFFER_H_
#define MEDIABUFFER_H_

#include <stdlib.h>
#include "lgabriellib/Buffer.h"

Buffer::Buffer()
:	sequenceNumber(1),
	timeStamp(0),
	begin(0),
	end(0)
{
	memset(array, blank_char, buffer_size);
}

bool Buffer::Put(int ts, void * data, int datalen) {
    int beginF = begin + MsToBytes(ts - timeStamp);
    int endF = beginF + datalen;

    if(beginF >= begin && (endF < buffer_size || endF % buffer_size < begin)) {
        if(endF < buffer_size) {
            memcpy(array + beginF, data, datalen);

            end = max(end, endF % buffer_size);
        } else if(beginF < buffer_size) {
            int len1 = buffer_size - beginF;
            int len2 = datalen - len1;

            memcpy(array + beginF, data, len1);
            memcpy(array, ((char *)data) + len1, len2);

            end = endF % buffer_size;
        } else {
            memcpy(array + beginF % buffer_size, data, datalen);

            end = max(end, endF % buffer_size);
        }
        return true;
    }
    return false;
}

bool Buffer::Get(int & seqno, int & ts, void * data, int & datalen) {
    if(begin < end && end - begin >= out_frame_size) {
        seqno = sequenceNumber++;
        ts = timeStamp;

        memcpy(data, array + begin, out_frame_size);
        memset(array + begin, blank_char, out_frame_size);

        datalen = out_frame_size;

        timeStamp = BytesToMs(begin + out_frame_size);
        begin += out_frame_size;

        return true;
    } else if(begin > end && buffer_size - begin + end > out_frame_size) {
        if(begin + out_frame_size < buffer_size) {
            seqno = sequenceNumber++;
            ts = timeStamp;

            memcpy(data, array + begin, out_frame_size);
            memset(array + begin, blank_char, out_frame_size);

            datalen = out_frame_size;
        } else {
            int len1 = buffer_size - begin;
            int len2 = out_frame_size - len1;

            seqno = sequenceNumber++;
            ts = timeStamp;

            memcpy(data, array + begin, len1);
            memset(array + begin, blank_char, len1);

            memcpy(((char *)data) + len1, array, len2);
            memset(array, blank_char, len2);

            datalen = out_frame_size;
        }
        timeStamp += BytesToMs(out_frame_size);
        begin = (begin + out_frame_size) % buffer_size;

        return true;
    }
    return false;
}

#endif // BUFFER_H_
